package com.inspur.cloud.service.dataspace;

import com.inspur.cloud.entity.dataspace.UserEntity;
import com.inspur.cloud.entity.dataspace.UserResourceRelationEntity;
import com.inspur.cloud.entity.dataspace.YarnResourceEntity;
import com.inspur.cloud.entity.dataspace.ao.resource.DistributeAO;
import com.inspur.cloud.entity.dataspace.common.OpEntityResult;
import com.inspur.cloud.entity.dataspace.common.PageReqParam;
import com.inspur.cloud.entity.dataspace.common.PageResult;
import com.inspur.cloud.entity.dataspace.dto.UserResourceRelationDTO;
import com.inspur.cloud.entity.dataspace.dto.YarnDTO;
import com.inspur.cloud.entity.dataspace.dto.YarnInfo;
import com.inspur.cloud.entity.dataspace.vo.YarnParam;
import com.inspur.cloud.entity.dataspace.vo.YarnReq;
import com.inspur.cloud.entity.dataspace.vo.YarnVO;
import com.inspur.cloud.enums.PermissionEnum;
import com.inspur.cloud.enums.ResourceTypeEnum;
import com.inspur.cloud.exception.BusinessException;
import com.inspur.cloud.security.AuthorizationHelper;
import com.inspur.cloud.util.StringUtil;
import com.inspur.cloud.util.TConstants;
import com.inspur.cloud.util.TimeHelper;
import com.inspur.cloud.util.UtilTenant;
import org.hibernate.query.internal.NativeQueryImpl;
import org.hibernate.transform.Transformers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.persistence.criteria.Predicate;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
public class YarnManagerService {
    @Autowired
    private YarnResourceService yarnResourceService;
    @PersistenceContext
    private EntityManager em;
    @Autowired
    UserService userService;
    @Autowired
    UserResRelationSerivce userResRelationService;
    @Autowired
    YarnService yarnService;
    @Autowired
    RangerService rangerService;
    @Autowired
    UserResourceRelationService userResourceRelationService;
    @Autowired
    AuthService authService;

    public PageResult<YarnVO> showForUser(PageReqParam<YarnReq> yarnReq) {
        return getList(yarnReq);
    }

    /**
     * 管理员可以查看不是自己创建并且没有给自己赋权限的资源，ur表关联有问题，所以单独抽出来
     *
     * @param yarnReq
     * @return
     */
    public PageResult<YarnVO> showForAdmin(PageReqParam<YarnReq> yarnReq) {
        return getList(yarnReq);
    }


    public PageResult<YarnVO> getList(PageReqParam<YarnReq> yarnReq) {
        PageResult<YarnVO> ret = new PageResult<>();
        StringBuilder sql = new StringBuilder(" SELECT h.* FROM yarn_resource h ");
        StringBuilder countSql = new StringBuilder(" SELECT count(*) from (SELECT count(*) FROM yarn_resource h ");
        StringBuilder condition = new StringBuilder(" WHERE h.status=1 ");
        if (yarnReq.getReqParam().getResourceId() != null && yarnReq.getReqParam().getResourceId() != 0) {
            YarnResourceEntity yarn=yarnResourceService.findYarnResourceEntityById(yarnReq.getReqParam().getResourceId());
            if(yarn==null){
                ret.setCount(1L);
                ret.setMsg("当前资源ID不存在");
                ret.setCode(-1);
                return ret;
            }
            condition.append(" AND h.parent_id=").append(yarnReq.getReqParam().getResourceId());
            condition.append(" AND h.queue_name!='").append(yarn.getQueueName()+"_"+TConstants.YARN_DEFAULT).append("' ");//排除user_default
        } else {
            condition.append(" AND h.parent_id=0 ");
        }
        if (!StringUtil.isEmpty(yarnReq.getReqParam().getResourceName())) {
            condition.append(" AND h.queue_name  like '%").append(yarnReq.getReqParam().getResourceName()).append("%'");
        }
        condition.append(" AND h.queue_name!='").append(TConstants.YARN_DEFAULT).append("' ");//排除default
        if(!AuthorizationHelper.isAdmin()){
            Specification<UserResourceRelationEntity> specification = (Specification<UserResourceRelationEntity>) (root, query, cb) -> {
                List<Predicate> list = new ArrayList<>();
                list.add(cb.equal(root.get("userId"), AuthorizationHelper.getUser().getId()));
                list.add(cb.equal(root.get("resourceType"), ResourceTypeEnum.YARN.name()));
                if (!StringUtil.isEmpty(yarnReq.getReqParam().getResourceName())) {
                    list.add(cb.like(root.get("resourceContent"), "%" + yarnReq.getReqParam().getResourceName() + "%"));
                }
                return cb.and(list.toArray(new Predicate[list.size()]));
            };
            List<UserResourceRelationEntity> urList = userResRelationService.findAll(specification);
            List<Integer> idList=new ArrayList<>();
            if(urList==null|| urList.size()==0){
                ret.setCount(0L);
                ret.setMsg("查询结果为空");
                ret.setCode(1);
                return ret;
            }
            for (UserResourceRelationEntity ur : urList) {
                idList.add(ur.getResourceId());
                if(ur.getResourceLevel()==2){//是二级队列，需要找出一级队列id，用于显示
                    YarnResourceEntity yarn=yarnResourceService.findYarnResourceEntityById(ur.getResourceId());
                    if(yarn!=null){
                        idList.add(yarn.getParentId());
                    }
                }
            }
            String ids = StringUtil.concatIntListDistinct(idList, ",");
            condition.append(" AND h.id in ( ").append(ids).append(" )");
        }
        condition.append(" group by h.id ");
        countSql.append(condition).append(") aa");
        sql.append(condition).append(" ORDER BY h.upd_date  DESC limit :limit ,:offset");
        Query countQuery = em.createNativeQuery(countSql.toString());
        BigInteger count = (BigInteger) countQuery.getSingleResult();
        Integer limit = (yarnReq.getPageIndex() - 1) * yarnReq.getPageSize();
        Query listQuery = em.createNativeQuery(sql.toString());
        listQuery.setParameter("limit", limit);
        listQuery.setParameter("offset", yarnReq.getPageSize());
        listQuery.unwrap(NativeQueryImpl.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
        List<Map> result = listQuery.getResultList();
        List<YarnVO> voList = new ArrayList<>();
        for (Map map : result) {
            YarnVO yarnVO = new YarnVO();
            yarnVO.setRatio(map.get("ratio") != null ? Float.valueOf(map.get("ratio").toString()) : 0.0F);
            yarnVO.setQueueName(map.get("queue_name") != null ? map.get("queue_name").toString() : "");
            yarnVO.setResourceId(Integer.valueOf(map.get("id").toString()));
            UserResourceRelationDTO userResourceRelationDTO = userResourceRelationService.queryUserByResourceIdExceptOwner(yarnVO.getResourceId(), ResourceTypeEnum.YARN, AuthorizationHelper.getUser().getId());
            yarnVO.setTenantList(userResourceRelationDTO.getTannetList());
            yarnVO.setUserList(userResourceRelationDTO.getUserList());
            yarnVO.setParentId(map.get("parent_id") != null ? Integer.valueOf(map.get("parent_id").toString()) : 0);
            yarnVO.setLevel(map.get("level") != null ? Integer.valueOf(map.get("level").toString()) : -1);
            yarnVO.setInsDate(map.get("ins_date") != null ? TimeHelper.StringToDate(map.get("ins_date").toString()) : null);
            yarnVO.setUpdDate(map.get("upd_date") != null ? TimeHelper.StringToDate(map.get("upd_date").toString()) : null);
            UserResourceRelationEntity userResourceRelationEntity = userResRelationService.findFirstByResourceIdAndUserIdAndResourceType(yarnVO.getResourceId(), AuthorizationHelper.getUser().getId(), ResourceTypeEnum.YARN.name());
            if (userResourceRelationEntity != null) {
                yarnVO.setPowerList(userResourceRelationEntity.getAuthor());
            }
            Integer creator = map.get("creator") != null ? Integer.valueOf(map.get("creator").toString()) : null;
            if (creator != null) {//hive的表和列创建者来自后台,这里大概率是取不到的
                UserEntity user = userService.findUserById(creator);
                yarnVO.setCreator(user == null ? "" : user.getName());
            }
            voList.add(yarnVO);
        }
        ret.setPageList(voList);
        ret.setCount(count.longValue());
        ret.setCode(1);
        return ret;
    }

    @Transactional(transactionManager = "transactionManagerDataspace")
    public OpEntityResult<Integer> addRes(YarnParam yarnParam) throws Exception {
        sync(0, 1);
        OpEntityResult<Integer> opEntityResult = new OpEntityResult<>();
        Date now = new Date();
        Float sum = 0.0F;
        List<String> queueNameList = new ArrayList<>();
        YarnResourceEntity parent = null;
        String resource;//ranger授权的拼接字符串
        String queueName = null;//本次新建的queueName
        Integer resourceId = 0;//本次插入队列的ID，后面会更新，UR表需要用到
        Integer size = yarnParam.getYarnInfoList().size();
        String[] queueArr = new String[size];
        String[] ratioArr = new String[size];
        String userDefault = "";//租户下面的默认队列
        for (int i = 0; i < size; i++) {
            YarnDTO yarnInfo = yarnParam.getYarnInfoList().get(i);
            Float capacity = yarnInfo.getRatio();
            sum += capacity;
            if (queueNameList.contains(yarnInfo.getQueueName())) {
                throw new BusinessException("不可创建同名队列");
            }
            if (yarnInfo.getRatio() == 0f) {
                throw new BusinessException("队列占比不能为0");
            }
            queueNameList.add(yarnInfo.getQueueName());
            queueArr[i] = yarnInfo.getQueueName();
            ratioArr[i] = String.format("%f", yarnInfo.getRatio());

        }
        if (sum != 100.0F) {
            return OpEntityResult.fail("队列占比之和必须等于100");
        }
        List<String> queueList = yarnResourceService.findQueueNameByParentId(yarnParam.getParentId());
        if ((yarnParam.getYarnInfoList() != null) && yarnParam.getYarnInfoList().size() > queueList.size() + 2) {
            return OpEntityResult.fail("每次只允许新建一个队列");
        }
        if (yarnParam.getParentId() != 0) {
            parent = yarnResourceService.findYarnResourceEntityById(yarnParam.getParentId());
            userDefault = parent.getQueueName() + "_default";
            if (parent == null) {
                return OpEntityResult.fail("指定的父资源不存在");
            }
            if(sum<100.0F){//队列占比之和不到100(留待以后需求更改,目前不会走到这个分支)
                for (int i = 0; i < size; i++) {
                    YarnDTO yarnInfo = yarnParam.getYarnInfoList().get(i);
                    if(userDefault.equals(yarnInfo.getQueueName())){//找到user_default队列
                        Float defaultRatio=yarnInfo.getRatio();
                        defaultRatio+=(100.0F-sum);
                        ratioArr[i] = String.format("%f", defaultRatio);
                        yarnInfo.setRatio(defaultRatio);
                    }
                }
            }
        }

        String powerStr = StringUtil.isEmpty(yarnParam.getPowerList()) ? PermissionEnum.getAllPermissionByType(ResourceTypeEnum.YARN.getType()) : yarnParam.getPowerList();
        List<UserEntity> userList = new ArrayList<>();
        if (yarnParam.getTenantList() != null) {
            userList = userService.findByNameIn(yarnParam.getTenantList());
        }
        if (yarnParam.getUserList() != null) {
            userList.addAll(userService.findByNameIn(yarnParam.getUserList()));
        }
        if (yarnParam.getTenantIdList() != null && yarnParam.getTenantIdList().size() > 0) {
            userList = userService.findByIdIn(yarnParam.getTenantIdList());
        }
        if (yarnParam.getUserIdList() != null && yarnParam.getUserIdList().size() > 0) {
            userList.addAll(userService.findByIdIn(yarnParam.getUserIdList()));
        }
        //把创建者自己加入资源分配表
        userList.add(AuthorizationHelper.getUser());
        if(!AuthorizationHelper.isAdmin() && yarnParam.getLevel()<=1){ //租户创建子队列时不加管理员权限
            userList.add(userService.findUserById(TConstants.ADMIN_ID));
        }
        //yarn的新增不是简单的新增
        for (int i = 0; i < size; i++) {
            YarnDTO yarnInfo = yarnParam.getYarnInfoList().get(i);
            Float capacity = yarnInfo.getRatio();
            YarnResourceEntity yarn = yarnResourceService.findFirstByQueueNameAndParentId(yarnInfo.getQueueName(), yarnParam.getParentId());
            if (yarn != null) {
                yarn.setRatio(capacity);
                yarn.setUpdDate(now);
                yarnResourceService.save(yarn);
            } else {
                YarnResourceEntity yarnGlobal=yarnResourceService.findFirstByQueueName(yarnInfo.getQueueName());
                if(yarnGlobal!=null){
                    throw new BusinessException("全局yarn队列中不允许存在同名队列");
                }
                yarn = new YarnResourceEntity();
                if (yarnParam.getParentId() == 0) {
                    yarn.setLevel(1);
                } else {
                    yarn.setLevel(2);
                }
                if (AuthorizationHelper.isAdmin()) {
                    //创建公共资源
                    yarn.setOwner(1);
                } else {
                    //创建租户资源
                    yarn.setOwner(AuthorizationHelper.getUser().getId());
                }
                //调接口，然后入库 测试
                yarn.setQueueName(yarnInfo.getQueueName());
                yarn.setParentId(yarnParam.getParentId());
                yarn.setRatio(capacity);
                yarn.setStatus(1);
                yarn.setInsDate(now);
                yarn.setUpdDate(now);
                yarn.setCreator(AuthorizationHelper.getUser().getId());
                yarnResourceService.saveAndFlush(yarn);//资源入库
                if (!yarnInfo.getQueueName().equals(TConstants.YARN_DEFAULT) &&
                        !yarnInfo.getQueueName().equals(userDefault)) {
                    resourceId = yarn.getId();
                    queueName = yarnInfo.getQueueName();
                }
            }
        }
        //根据用户名查找用户，然后建立用户-资源关系
        if (yarnParam.getLevel() == 1) {
            //调大数据的接口
            boolean editYarnQueueResult = yarnService.editYarnQueue(TConstants.ROOT, queueArr, ratioArr);
            if (!editYarnQueueResult) {
                throw new BusinessException("修改 Yarn 队列失败");
            }
            resource = TConstants.ROOT + "." + queueName;
        } else {
            boolean editYarnQueueResult = yarnService.editYarnQueue(parent.getQueueName(), queueArr, ratioArr);
            if (!editYarnQueueResult) {
                throw new BusinessException("修改 Yarn 队列失败");
            }
            resource = TConstants.ROOT + "." + parent.getQueueName() + "." + queueName;
        }
        List<String> nameList = new ArrayList<>();
        for (UserEntity userEntity : userList) {//userList不可能为空
            UserResourceRelationEntity ur = new UserResourceRelationEntity();
            ur.setResourceId(resourceId);
            ur.setInsDate(now);
            ur.setUpdDate(now);
            ur.setStatus(1);
            ur.setUserId(userEntity.getId());
            ur.setResourceType(ResourceTypeEnum.YARN.name());
            ur.setResourceContent(queueName);
            ur.setAuthor(powerStr);
            ur.setResourceLevel(yarnParam.getLevel());
            userResRelationService.save(ur);
            nameList.add(userEntity.getName());//一次赋权，优化效率

            //DEFAULT队列也要进数据库
            if (yarnParam.getLevel() == 2 && queueList.size() == 0) {
                YarnResourceEntity yarnDefault = yarnResourceService.findFirstByQueueNameAndParentId(parent.getQueueName() + "_default", yarnParam.getParentId());
                UserResourceRelationEntity urDefault = new UserResourceRelationEntity();
                urDefault.setResourceId(yarnDefault != null ? yarnDefault.getId() : 0);
                urDefault.setInsDate(now);
                urDefault.setUpdDate(now);
                urDefault.setStatus(1);
                urDefault.setUserId(userEntity.getId());
                urDefault.setResourceType(ResourceTypeEnum.YARN.name());
                urDefault.setResourceContent(parent.getQueueName() + "_default");
                urDefault.setAuthor(powerStr);
                urDefault.setResourceLevel(yarnParam.getLevel());
                userResRelationService.save(urDefault);
            }

        }
        rangerService.setPermissionInRanger(ResourceTypeEnum.YARN.name().toLowerCase(), resource, powerStr, StringUtil.concat(nameList, "|"));
        if (yarnParam.getLevel() == 2 && queueList != null && queueList.size() == 0) {//第一次创建子队列的时候
            String resourceDefault = TConstants.ROOT + "." + parent.getQueueName() + "." + parent.getQueueName() + "_default";
            rangerService.setPermissionInRanger(ResourceTypeEnum.YARN.name().toLowerCase(), resourceDefault, powerStr, StringUtil.concat(nameList, "|"));
        }

        opEntityResult.setCode(1);
        opEntityResult.setMsg("yarn资源创建成功");
        opEntityResult.setData(resourceId);
        return opEntityResult;
    }

    @Transactional(transactionManager = "transactionManagerDataspace")
    public OpEntityResult<Integer> modifyRes(YarnParam yarnParam) throws Exception {
        OpEntityResult<Integer> opEntityResult = new OpEntityResult<>();
        Date now = new Date();
        Float sum = 0.0F;
        List<String> queueNameList = new ArrayList<>();
        YarnResourceEntity parent = null;
        int size = yarnParam.getYarnInfoList().size();
        String[] queueArray = new String[size];
        String[] ratioArray = new String[size];
        for (int i = 0; i < size; i++) {
            YarnDTO yarnInfo = yarnParam.getYarnInfoList().get(i);
            Float capacity = yarnInfo.getRatio();
            sum += capacity;
            if (queueNameList.contains(yarnInfo.getQueueName())) {
                throw new BusinessException("不可创建同名队列");
            }
            if (yarnInfo.getRatio() == 0f) {
                throw new BusinessException("队列占比不能为0");//只有default可以为0
            }
            queueNameList.add(yarnInfo.getQueueName());
            queueArray[i] = yarnInfo.getQueueName();
            ratioArray[i] = String.format("%f", yarnInfo.getRatio());
        }
        if (sum > 100.0F) {
            return OpEntityResult.fail("队列占比之和需要等于100");
        }
        List<YarnResourceEntity> queueList = yarnResourceService.findByParentId(yarnParam.getParentId());
        if (queueList.size() != yarnParam.getYarnInfoList().size()) {
            return OpEntityResult.fail("队列参数不匹配，请同步后重新编辑");
        }
        if (yarnParam.getLevel() == 1) {
            boolean editYarnQueueResult = yarnService.editYarnQueue(TConstants.ROOT, queueArray, ratioArray);
            if (!editYarnQueueResult) {
                throw new BusinessException("修改 Yarn 队列失败");
            }
        } else {
            parent = yarnResourceService.findYarnResourceEntityById(yarnParam.getParentId());
            if (parent == null) {
                return OpEntityResult.fail("指定的父资源不存在");
            }
            String auth = authService.getSourceAuth(yarnParam.getParentId(), AuthorizationHelper.getUser().getId(), ResourceTypeEnum.YARN.name());
            if (!AuthorizationHelper.isAdmin()) {//
                if (!AuthorizationHelper.getUser().getId().equals(parent.getOwner()) && StringUtil.isEmpty(auth)) {
                    return OpEntityResult.fail("当前用户不允许编辑该资源ID对应yarn队列");
                }
            }
            boolean editYarnQueueResult = yarnService.editYarnQueue(parent.getQueueName(), queueArray, ratioArray);
            if (!editYarnQueueResult) {
                throw new BusinessException("修改 Yarn 队列失败");
            }
        }

        for (YarnResourceEntity yarnResourceEntity : queueList) {
            Float newRatio = 0.f;//新的ratio
            for (YarnDTO yarnInfo : yarnParam.getYarnInfoList()) {
                if (yarnInfo.getQueueName().equals(yarnResourceEntity.getQueueName())) {
                    newRatio = yarnInfo.getRatio();
                    break;
                }
            }
            yarnResourceEntity.setRatio(newRatio);
            if(yarnResourceEntity.getRatio()>100f){
                yarnResourceEntity.setRatio(100f);//额度肯定不能超过100，正常情况不会，但是同步出问题了就会
            }
            yarnResourceEntity.setUpdDate(now);
            yarnResourceService.save(yarnResourceEntity);
        }
        opEntityResult.setCode(1);
        opEntityResult.setMsg("yarn资源编辑成功");
        return opEntityResult;
    }

    @Transactional(transactionManager = "transactionManagerDataspace")
    public OpEntityResult<Integer> distributeRes(DistributeAO yarnDistributeAO) throws Exception {
        OpEntityResult<Integer> opEntityResult = new OpEntityResult<>();
        YarnResourceEntity yarn = yarnResourceService.findYarnResourceEntityById(yarnDistributeAO.getResourceId());
        if (yarn == null) {
            return new OpEntityResult<>(-1, "指定的资源不存在", -1);
        }
        Integer result=userResourceRelationService.distribute(yarnDistributeAO,ResourceTypeEnum.YARN,false);
        opEntityResult.setCode(1);
        if(UtilTenant.empty(yarnDistributeAO)) {
            opEntityResult.setMsg("分配已置空");
        }else{
            opEntityResult.setMsg("YARN资源分配成功");
        }
        opEntityResult.setData(result);
        return opEntityResult;
    }


    @Transactional(transactionManager = "transactionManagerDataspace")
    public OpEntityResult<Integer> delRes(Integer resourceId) {
        OpEntityResult<Integer> opEntityResult = new OpEntityResult<>();
        Date now = new Date();
        YarnResourceEntity yarn = yarnResourceService.findYarnResourceEntityById(resourceId);
        if (yarn == null) {
            return OpEntityResult.fail("该资源ID对应yarn队列不存在");
        }
        String auth = authService.getSourceAuth(resourceId, AuthorizationHelper.getUser().getId(), ResourceTypeEnum.YARN.name());
        if (!AuthorizationHelper.isAdmin()) {//
            if (!AuthorizationHelper.getUser().getId().equals(yarn.getOwner()) && StringUtil.isEmpty(auth)) {
                return OpEntityResult.fail("当前用户不允许删除该资源ID对应yarn队列");
            }
        }
        if (yarn.getQueueName().equals(TConstants.YARN_DEFAULT)) {//因为yarn里队列不能重名，这里不考虑层级了
            return OpEntityResult.fail("default队列不能删除");
        }
        List<YarnResourceEntity> yarnList;
        String parentQueue = "";//父队列名字
        if (yarn.getLevel() == 1) {
            yarnList = yarnResourceService.findByParentIdExceptSelf(0, resourceId);
            parentQueue = TConstants.ROOT;
        } else {
            yarnList = yarnResourceService.findByParentIdExceptSelf(yarn.getParentId(), resourceId);
            YarnResourceEntity parent = yarnResourceService.findYarnResourceEntityById(yarn.getParentId());
            if (parent == null) {
                return OpEntityResult.fail("父资源不存在");
            }
            parentQueue = parent.getQueueName();
        }
        if (yarnList.size() == 0) {
            return OpEntityResult.fail("yarn队列异常");
        }
        Integer size = yarnList.size();
        String[] queueArr = new String[size];
        String[] ratioArr = new String[size];
        for (int i = 0; i < size; i++) {
            YarnResourceEntity yarnInfo = yarnList.get(i);
            queueArr[i] = yarnInfo.getQueueName();
            ratioArr[i] = String.format("%f", yarnInfo.getRatio());
            if (yarnInfo.getQueueName().equals(TConstants.YARN_DEFAULT) ||
                    yarnInfo.getQueueName().endsWith("_" + TConstants.YARN_DEFAULT)) {
                Float ratioDel = yarn.getRatio();//释放出来的额度
                ratioArr[i] = String.format("%f", yarnInfo.getRatio() + ratioDel);
                yarnInfo.setRatio(yarnInfo.getRatio() + ratioDel);
                if(yarnInfo.getRatio()>100f){
                    yarnInfo.setRatio(100f);//额度肯定不能超过100，正常情况不会，但是同步出问题了就会
                }
                yarnInfo.setUpdDate(now);
                yarnResourceService.save(yarnInfo);//default队列需要更新
            }
        }
        yarnService.delYarnQueue(parentQueue, queueArr, ratioArr);
        delYarnInDb(yarn);
        if(yarn.getLevel() == 2){//如果删除当前队列后只剩default队列的话，就删除default
            yarnList = yarnResourceService.findByParentId(yarn.getParentId());
            if(yarnList!=null && yarnList.size()==1){
                YarnResourceEntity defaultYarn=yarnList.get(0);
                if(defaultYarn.getQueueName().endsWith("_default")){
                    yarnService.delYarnQueue(parentQueue, new String[]{""},new String[]{""});
                    delYarnInDb(defaultYarn);
                }

            }
        }

        opEntityResult.setCode(1);
        opEntityResult.setMsg("yarn资源已删除");
        opEntityResult.setData(resourceId);
        return opEntityResult;
    }

    @Transactional(transactionManager = "transactionManagerDataspace")
    public OpEntityResult<Integer> sync(Integer resourceId, Integer level) {
        Date now = new Date();
        OpEntityResult<Integer> opEntityResult = new OpEntityResult<>();
        String powerStr = PermissionEnum.getAllPermissionByType(ResourceTypeEnum.YARN.getType());
        YarnInfo yarnInfo = yarnService.getQueueInfoFalse();
        if (yarnInfo == null || yarnInfo.getQueue() == null || yarnInfo.getQueue().size() == 0) {
            return OpEntityResult.fail("未获取到有效同步信息");
        }
        if (level == 1) {//同步第一级
            List<YarnInfo> roots = yarnInfo.getQueue();
            List<String> queueFromServer = new ArrayList<>();//来自服务器的同步数据
            for (YarnInfo info : roots) {
                YarnResourceEntity yarn = yarnResourceService.findFirstByQueueNameAndParentId(info.getQueueName(), 0);
                queueFromServer.add(info.getQueueName());
                Integer uid = AuthorizationHelper.getUser().getId();
                Float capacity = info.getCapacity() != null ? Float.valueOf(info.getCapacity()) : 0.0f;
                if (yarn == null) {
                    yarn = new YarnResourceEntity();
                    yarn.setOwner(1);//这里有待完善
                    yarn.setRatio(capacity);
                    if(yarn.getRatio()>100f){
                        yarn.setRatio(100f);//额度肯定不能超过100，正常情况不会，但是同步出问题了就会
                    }
                    yarn.setStatus(TConstants.RES_STATUS_AVAILABLE);
                    yarn.setLevel(1);
                    yarn.setQueueName(info.getQueueName());
                    yarn.setParentId(0);
                    yarn.setInsDate(now);
                    yarn.setUpdDate(now);
                    yarnResourceService.save(yarn);

                    UserResourceRelationEntity ur = userResRelationService.findFirstByResourceIdAndUserIdAndResourceType(yarn.getId(), uid, ResourceTypeEnum.YARN.name());
                    if (ur == null) {
                        ur = new UserResourceRelationEntity();
                        ur.setResourceId(yarn.getId());
                        ur.setInsDate(now);
                        ur.setUpdDate(now);
                        ur.setStatus(TConstants.RES_STATUS_AVAILABLE);
                        ur.setUserId(uid);
                        ur.setResourceType(ResourceTypeEnum.YARN.name());
                        ur.setResourceContent(yarn.getQueueName());
                        ur.setAuthor(powerStr);
                        ur.setResourceLevel(yarn.getLevel());
                        userResRelationService.save(ur);
                    } else {
                        ur.setUpdDate(now);
                        userResRelationService.save(ur);
                    }
                    String resource = TConstants.ROOT + "." + info.getQueueName();
                    rangerService.setPermissionInRanger(ResourceTypeEnum.YARN.name().toLowerCase(), resource, powerStr, TConstants.ADMIN_NAME);
                } else {
                    yarn.setRatio(capacity);
                    if(yarn.getRatio()>100f){
                        yarn.setRatio(100.0f);//额度肯定不能超过100，正常情况不会，但是同步出问题了就会
                    }
                    yarnResourceService.save(yarn);

                }
            }//end for
            List<String> queueFromData = yarnResourceService.findQueueNameByParentId(0);//找出数据库里的第一级队列
            for (String q : queueFromData) {
                if (!queueFromServer.contains(q)) {
                    //数据库中有，但是服务器上没的，那就删除（删除数据库中的就不讲究父子顺序了）
                    YarnResourceEntity yarnData = yarnResourceService.findFirstByQueueNameAndParentId(q, 0);
                    if (yarnData != null) {
                        yarnResourceService.deleteById(yarnData.getId());//删除爹
                        userResRelationService.delByResourceId(yarnData.getId(), ResourceTypeEnum.YARN.name());
                        String resource = TConstants.ROOT + "." + yarnData.getQueueName();
                        rangerService.setPermissionInRanger(ResourceTypeEnum.YARN.name().toLowerCase(), resource, "", TConstants.ADMIN_NAME);
                        List<Integer> sonIds = yarnResourceService.findIdByParentId(yarnData.getId());//找出儿子来删除
                        yarnResourceService.deleteByParentId(yarnData.getId());
                        if (sonIds != null && sonIds.size() > 0) {
                            userResRelationService.delByResourceIdList(sonIds, ResourceTypeEnum.YARN.name());//这里有ranger权限没删除，需要优化
                        }
                    }
                }
            }
            opEntityResult.setData(roots.size());
            opEntityResult.setCode(1);
            opEntityResult.setMsg("第一层数据同步成功");
            return opEntityResult;
        } else if (level == 2) {
            YarnResourceEntity yarnUser = yarnResourceService.findYarnResourceEntityById(resourceId);
            if (yarnUser == null) return OpEntityResult.fail("资源ID不存在");
            List<YarnInfo> rootQueueList = yarnInfo.getQueue();
            List<YarnInfo> userQueueList = new ArrayList<>();
            List<String> queueFromServer = new ArrayList<>();//来自服务器的同步数据
            for (YarnInfo info : rootQueueList) {
                if (info.getQueueName().equals(yarnUser.getQueueName())) {
                    userQueueList = info.getQueue();
                    break;
                }
            }
            if (userQueueList == null || userQueueList.size() == 0) {
                List<Integer> sonIds = yarnResourceService.findIdByParentId(yarnUser.getId());//找出儿子来删除
                yarnResourceService.deleteByParentId(yarnUser.getId());
                if (sonIds != null && sonIds.size() > 0) {
                    userResRelationService.delByResourceIdList(sonIds, ResourceTypeEnum.YARN.name());//需要优化，ranger里也要删除对应数据
                }
                return OpEntityResult.of(1, "二级队列同步成功");
            }
            UserEntity user = userService.findUserById(yarnUser.getOwner());
            for (YarnInfo info : userQueueList) {
                queueFromServer.add(info.getQueueName());//加入到服务器队列
                YarnResourceEntity yarn = yarnResourceService.findFirstByQueueNameAndParentId(info.getQueueName(), yarnUser.getId());
                Float capacity = info.getCapacity() != null ? Float.valueOf(info.getCapacity()) : 0.0f;
                if (yarn == null) {
                    yarn = new YarnResourceEntity(info.getQueueName(), capacity, yarnUser.getOwner(), yarnUser.getId(), TConstants.RES_STATUS_AVAILABLE, 2);
                    if(yarn.getRatio()>100f){
                        yarn.setRatio(100f);//额度肯定不能超过100，正常情况不会，但是同步出问题了就会
                    }
                    yarn.setInsDate(now);
                    yarn.setUpdDate(now);
                    yarnResourceService.save(yarn);
                    UserResourceRelationEntity ur = userResRelationService.findFirstByResourceIdAndUserIdAndResourceType(yarn.getId(), yarn.getOwner(), ResourceTypeEnum.YARN.name());
                    if (ur == null) {
                        ur = new UserResourceRelationEntity();
                        ur.setResourceId(yarn.getId());
                        ur.setInsDate(now);
                        ur.setUpdDate(now);
                        ur.setStatus(TConstants.RES_STATUS_AVAILABLE);
                        ur.setUserId(yarn.getOwner());
                        ur.setResourceType(ResourceTypeEnum.YARN.name());
                        ur.setResourceContent(yarn.getQueueName());
                        ur.setAuthor(powerStr);
                        ur.setResourceLevel(yarn.getLevel());
                        userResRelationService.save(ur);

                        String resource = TConstants.ROOT + "." + yarnUser.getQueueName() + "." + yarn.getQueueName();
                        if (user != null) {
                            rangerService.setPermissionInRanger(ResourceTypeEnum.YARN.name().toLowerCase(), resource, powerStr, user.getName());
                        }
                    } else {
                        ur.setUpdDate(now);
                        userResRelationService.save(ur);
                    }
                } else {
                    yarn.setRatio(capacity);
                    if(yarn.getRatio()>100f){
                        yarn.setRatio(100f);//额度肯定不能超过100，正常情况不会，但是同步出问题了就会
                    }
                    yarnResourceService.save(yarn);
                }
            }

            List<String> queueFromData = yarnResourceService.findQueueNameByParentId(resourceId);//找出数据库里的第2级队列
            for (String q : queueFromData) {
                if (!queueFromServer.contains(q)) {
                    //数据库中有，但是服务器上没的，那就删除
                    YarnResourceEntity yarnData = yarnResourceService.findFirstByQueueNameAndParentId(q, resourceId);
                    if (yarnData != null) {
                        yarnResourceService.deleteById(yarnData.getId());
                        userResRelationService.delByResourceId(yarnData.getId(), ResourceTypeEnum.YARN.name());
                        String resource = TConstants.ROOT + "." + yarnUser.getQueueName() + "." + yarnData.getQueueName();
                        rangerService.setPermissionInRanger(ResourceTypeEnum.YARN.name().toLowerCase(), resource, "", TConstants.ADMIN_NAME);
                    }
                }
            }

            opEntityResult.setData(rootQueueList.size());
            opEntityResult.setCode(1);
            opEntityResult.setMsg("第2层数据同步成功");
            return opEntityResult;
        }
        return opEntityResult;
    }

    @Transactional(transactionManager = "transactionManagerDataspace")
    public List<YarnVO> queueList(Integer resourceId) {
        List<YarnResourceEntity> list = yarnResourceService.findByParentId(resourceId);
        List<YarnVO> voList = new ArrayList<>();
        for (YarnResourceEntity yarn : list) {
            YarnVO yarnVO = new YarnVO();
            yarnVO.setRatio(yarn.getRatio());
            if(yarnVO.getRatio()>100f){
                yarnVO.setRatio(100f);//额度肯定不能超过100，正常情况不会，但是同步出问题了就会
            }
            yarnVO.setQueueName(yarn.getQueueName());
            yarnVO.setResourceId(yarn.getId());
            voList.add(yarnVO);
        }
        if (resourceId != 0 && voList.size() == 0) {//是二级队列并且是空，塞一个default返回给前端
            YarnResourceEntity yarn = yarnResourceService.findYarnResourceEntityById(resourceId);
            if (yarn == null) {
                return voList;
            }
            YarnVO yarnVO = new YarnVO();
            yarnVO.setRatio(100f);
            yarnVO.setQueueName(yarn.getQueueName() + "_default");
            yarnVO.setResourceId(0);
            voList.add(yarnVO);
        }
        return voList;
    }

    @Transactional(transactionManager = "transactionManagerDataspace")
    public Integer delYarnInDb(YarnResourceEntity yarn) {
        userResourceRelationService.deleteAllUserRelations(yarn.getId(), ResourceTypeEnum.YARN.name());//删除资源对应权限
        if (yarn.getLevel() == 1) {//如果是一级队列，可能存在子队列
            List<YarnResourceEntity> son = yarnResourceService.findByParentId(yarn.getId());
            if (son == null || son.size() == 0) {//没有儿子的话要删除自己再返回
                yarnResourceService.deleteById(yarn.getId());
                return yarn.getId();
            }
            //有儿子需要删除儿子的关系和数据
            for (YarnResourceEntity yarnSon : son) {
                userResourceRelationService.deleteAllUserRelations(yarnSon.getId(), ResourceTypeEnum.YARN.name());//删除儿子对应权限
            }
            yarnResourceService.deleteByParentId(yarn.getId());//批量删除儿子资源
        }
        yarnResourceService.deleteById(yarn.getId());//删除资源
        return yarn.getId();
    }

}
